/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *	  http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.milib.tools {
	import com.googlecode.milib.base.IMLBroadcasterListener;
	import com.googlecode.milib.base.MLActionClass;
	import com.googlecode.milib.service.MLLoader;
	import com.googlecode.milib.vo.MLEventInfo;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;

	/**
	 * @author Marek Brun
	 */
	public class CachedLoadedImage extends MLActionClass implements IMLBroadcasterListener {

		private static const servicedObjects : Dictionary = new Dictionary(true);		private static const urlToRequest : Dictionary = new Dictionary(true);
		private var loader:MLLoader;
		private var request:URLRequest;
		private static var defaultLoaderContext:LoaderContext;		private var loaderContext:LoaderContext;

		public function CachedLoadedImage(acces:Private, request:URLRequest, loaderContext:LoaderContext=null) {
			this.request=request;
			if(!loaderContext){
				if(!defaultLoaderContext){
					defaultLoaderContext=new LoaderContext(false, ApplicationDomain.currentDomain);
				}
				loaderContext=defaultLoaderContext;
			}else{
				this.loaderContext=loaderContext;
			}
		}
		
		public function getLoader():MLLoader {
			return loader;
		}
		
		public function getProgress():Number {
			return loader.getProgress();
		}

		public function getGotImage():Boolean {
			if(!loader){ return false; }
			return loader.isSuccess;
		}
		
		public function getBitmapData():BitmapData {
			return Bitmap(loader.loader.content).bitmapData;
		}
		
		public function getNewBitmapData():BitmapData {
			return Bitmap(loader.loader.content).bitmapData.clone();
		}
		
		override protected function doStart():Boolean {
			if(loader){
				if(!loader.getIsRunning()){
					CallInNextFrame.addMethod(finish);
				}
				return true;
				//throw new Error('Can be started only one time');
			}
			loader=new MLLoader();
			loader.setup(request, loaderContext);
			loader.addListener(this);
			loader.start();
			return true;
		}
		
		override protected function doFinish():Boolean {
			_isSuccess=loader.isSuccess;
			return true;
		}
		
		public function getURL():String {
			return request.url;
		}

		public static function forInstance(request:URLRequest):CachedLoadedImage {
			if(servicedObjects[request]){
				return servicedObjects[request];
			}else{
				servicedObjects[request]=new CachedLoadedImage(null, request);
				return servicedObjects[request];
			}
		}
		
		public static function forInstanceAsString(url:String):CachedLoadedImage {
			if(!urlToRequest[url]){
				urlToRequest[url]=new URLRequest(url);
			}
			return forInstance(urlToRequest[url]);
		}
		
		public function unloadImage():void {
			_isSuccess=false;
			Bitmap(loader.loader.content).bitmapData.dispose();
			loader.removeListener(this);
			loader.dispose();
		}
		
//********************************************************************************************
//		events for CachedLoadedImage
//********************************************************************************************
		public function onEvent(ev:MLEventInfo):void {
			switch(ev.hero){
				case loader:
					switch(ev.event) {
						case loader.event_ActionFinish:
							finish();
						break;
					}
				break;
			}
		}
		
	}

}
internal class Private {}